package nju.jun.reader.tieba.crawler;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import nju.jun.reader.tieba.TiebaListener;
import nju.jun.reader.tieba.data.TiebaNovelContentListener;
import nju.jun.reader.tieba.data.TiebaNovelWriter;
import nju.jun.reader.tieba.model.TiebaNovel;
import nju.jun.reader.tieba.model.TiebaNovelChapter;

public class TiebaNovelCrawler implements Runnable {
	
	private List<TiebaListener> listeners;
	
	private TiebaNovel novel;
	
	private TiebaHtmlParser parser;

	public TiebaNovelCrawler() {
		parser = new TiebaHtmlParser();
		
		// initialize content listener
		listeners = new ArrayList<TiebaListener>();
		listeners.add(new TiebaNovelWriter());
	}
	
	public TiebaNovelCrawler(TiebaNovel novel) {
		this();
		this.novel = novel;
	}
	
	public TiebaNovel getNovel() {
		return novel;
	}

	public void setNovel(TiebaNovel novel) {
		this.novel = novel;
	}
	
	public void onTiebaNovelContentReady(TiebaNovelChapter chapter) {
		for (TiebaListener listener : listeners) {
			if (listener instanceof TiebaNovelContentListener) {
				((TiebaNovelContentListener) listener).onContentReady(chapter);
			}
		}
	}

	@Override
	public void run() {
		int maxChapNo = 0;
		int maxVolNo = 0;
		List<TiebaNovelChapter> chapters = parser.getNovelChapters(novel);
		Iterator<TiebaNovelChapter> iter = chapters.iterator();
		while (iter.hasNext()) {
			TiebaNovelChapter chapter = iter.next();
			// TODO: need to make sure novel.getVolume and novel.getChapter return current max value\
			// hasn't been processed yet
			if (chapter.getVolumeNumber() > novel.getVolume() || chapter.getChapterNumber() > novel.getChapter()) {
				maxVolNo = Math.max(maxVolNo, chapter.getVolumeNumber());
				maxChapNo = Math.max(maxChapNo, chapter.getChapterNumber());
				
				parser.getNovelChapterContent(chapter);

				// trigger content write event
				onTiebaNovelContentReady(chapter);
			}
		}
		
		if (maxVolNo > novel.getVolume()) {
			novel.setVolume(maxVolNo);
		}
		
		if (maxChapNo > novel.getChapter()) {
			novel.setChapter(maxChapNo);
		}
	}

}